package cn.conac.rc.gateway.aop;

import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import com.alibaba.fastjson.JSON;

import cn.conac.rc.framework.utils.IpUtils;
import cn.conac.rc.gateway.common.vo.LogVo;
import cn.conac.rc.gateway.security.UserUtils;  
  

/**
 * 拦截器： 记录系统操作数据库表的日志
 *              主要针对增删改操作（C：增加 U：修改  D：删除）
 * @author lucj 
 */
@Component
@Aspect
public class LogAop {
	
	 private Logger logger =  LoggerFactory.getLogger(this.getClass());
  
    @Pointcut("execution(* cn.conac.rc.gateway..rest..*.cud*(..))")
    public void executeCudOper(){
  
    }  
  
    /** 
     * 前置通知，方法调用前被调用 
     * @param joinPoint 
     */  
    @Before("executeCudOper()")  
    public void doBeforeAdvice(JoinPoint joinPoint) {
    	try {
	        //获取RequestAttributes  
	        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
	        
	        //从获取RequestAttributes中获取HttpServletRequest的信息  
	        HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
	        
	       //保存所有请求参数，用于输出到日志中  
	        Set<Object> allParams = new LinkedHashSet<>(); 
	        
	    	//获取目标方法的参数信息  
	        Object[] args = joinPoint.getArgs();
	        
	        for(Object arg : args ){
	            if (arg  instanceof  Map<?, ?>) {  
	                //提取方法中的MAP参数，用于记录进日志中  
	                @SuppressWarnings("unchecked")  
	                Map<String, Object> map = (Map<String, Object>) arg;  
	                allParams.add(map);  
	            }else if( arg instanceof HttpServletRequest){  
	                // 增加判断是否有权限 TODO
	                //获取query string 或 posted form data参数  
	                Map<String, String[]>  paramMap = request.getParameterMap();  
	                if(paramMap != null && paramMap.size()>0){  
	                    allParams.add(paramMap);  
	                }  
	            }
	        }  
	        
	        LogVo logvo = new LogVo();
	        logvo.setMethod( joinPoint.getSignature().getDeclaringTypeName()+ "." + joinPoint.getSignature().getName());
	        logvo.setRemoteAddr(IpUtils.getRemoteAddr(request));
	        logvo.setLocalAddr(request.getLocalAddr());
	        logvo.setHttpMethod(request.getMethod());
	        logvo.setUserId(UserUtils.getCurrentUser().getId());
	        logvo.setUserName(UserUtils.getCurrentUser().getUsername());
	        logvo.setRequestUri(request.getRequestURI());
	        logvo.setUserAgent(request.getHeader("user-agent"));
	        
	        if(allParams.size() > 0 ) {
	        	logvo.setParams(JSON.toJSONString(allParams));
	        }
	       
	        //System.out.println(logvo.toString());
	        
	        logger.info("logvo : " + logvo.toString());
	        
    	}catch (Exception ex) {
    		// 记录发生异常的错误异常信息
    		logger.error("LogAop.doBeforeAdvice exception: " + ex.toString());
    	}
    }  
}  